--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Node / ReticulumProjects / MeshChatX.git / files / meshchatx / src / backend / interfaces / WebsocketServerInterface.py
Displaying Raw • Download
meshchatx/src/backend/interfaces/WebsocketServerInterface.py 22b4fcce096023ec706bab5449805e34a2912643 (22b4fcce) Text, 5.42 KB
T8b949e# SPDX-License-Identifier: 0BSD AND MIT
Tff7b72import T7ee787threading
Tff7b72import T7ee787time
Tff7b72import T7ee787RNS
Tff7b72from T7ee787RNST7ee787.T7ee787InterfacesT7ee787.T7ee787Interface Tff7b72import Te6edf3Interface
Tff7b72from T7ee787websocketsT7ee787.T7ee787syncT7ee787.T7ee787server Tff7b72import Te6edf3ServerTb4b4b4, Te6edf3ServerConnectionTb4b4b4, Te6edf3serve
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787interfacesT7ee787.T7ee787WebsocketClientInterface Tff7b72import Tb4b4b4(
Te6edf3WebsocketClientInterfaceTb4b4b4,
Tb4b4b4)
Tff7b72class T56d364WebsocketServerInterfaceTb4b4b4(Te6edf3InterfaceTb4b4b4)Tb4b4b4:
Te6edf3DEFAULT_IFAC_SIZE Tff7b72= T79c0ff16
Te6edf3RESTART_DELAY_SECONDS Tff7b72= T79c0ff5
Tff7b72def Tff7b72__str__Tb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffWebsocketServerInterface[Tffd700{Tff7b72selfTff7b72.Td2a8ffnameTffd700}Ta5d6ff/Tffd700{Tff7b72selfTff7b72.Td2a8fflisten_ipTffd700}Ta5d6ff:Tffd700{Tff7b72selfTff7b72.Td2a8fflisten_portTffd700}Ta5d6ff]Ta5d6ff"
Tb4b4b4)
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3ownerTb4b4b4, Te6edf3configurationTb4b4b4)Tb4b4b4:
Tffa657superTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ff__init__Tb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffowner Tff7b72= Te6edf3owner
Tff7b72selfTff7b72.Td2a8ffIN Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffOUT Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffHW_MTU Tff7b72= T79c0ff262144 T8b949e# 256KiB
Tff7b72selfTff7b72.Td2a8ffbitrate Tff7b72= T79c0ff1_000_000_000 T8b949e# 1Gbps
Tff7b72selfTff7b72.Td2a8ffmode Tff7b72= Te6edf3RNSTff7b72.Td2a8ffInterfacesTff7b72.Td2a8ffInterfaceTff7b72.Td2a8ffInterfaceTff7b72.Td2a8ffMODE_FULL
Tff7b72selfTff7b72.Td2a8ffserverTb4b4b4: Te6edf3Server Tff7b72| Tff7b72None Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffspawned_interfacesTb4b4b4: Tffa657listTb4b4b4[Te6edf3WebsocketClientInterfaceTb4b4b4] Tff7b72= Tb4b4b4[Tb4b4b4]
T8b949e# parse config
Te6edf3ifconf Tff7b72= Te6edf3InterfaceTff7b72.Td2a8ffget_config_objTb4b4b4(Te6edf3configurationTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffname Tff7b72= Te6edf3ifconfTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4)
Te6edf3listen_ip Tff7b72= Te6edf3ifconfTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fflisten_ipTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)
Te6edf3listen_port Tff7b72= Te6edf3ifconfTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fflisten_portTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)
T8b949e# ensure listen ip is provided
Tff7b72if Te6edf3listen_ip Tff7b72is Tff7b72NoneTb4b4b4:
Te6edf3msg Tff7b72= Ta5d6fffTa5d6ff"Ta5d6fflisten_ip is required for interface Ta5d6ff'Tffd700{Tff7b72selfTff7b72.Td2a8ffnameTffd700}Ta5d6ff'Ta5d6ff"
Tff7b72raise Tf85149SystemErrorTb4b4b4(Te6edf3msgTb4b4b4)
T8b949e# ensure listen port is provided
Tff7b72if Te6edf3listen_port Tff7b72is Tff7b72NoneTb4b4b4:
Te6edf3msg Tff7b72= Ta5d6fffTa5d6ff"Ta5d6fflisten_port is required for interface Ta5d6ff'Tffd700{Tff7b72selfTff7b72.Td2a8ffnameTffd700}Ta5d6ff'Ta5d6ff"
Tff7b72raise Tf85149SystemErrorTb4b4b4(Te6edf3msgTb4b4b4)
Tff7b72selfTff7b72.Td2a8fflisten_ip Tff7b72= Tffa657strTb4b4b4(Te6edf3listen_ipTb4b4b4)
Tff7b72selfTff7b72.Td2a8fflisten_port Tff7b72= Tffa657intTb4b4b4(Tffa657strTb4b4b4(Te6edf3listen_portTb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4)
T8b949e# run websocket server
Te6edf3thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Tff7b72selfTff7b72.Td2a8ffserveTb4b4b4)
Te6edf3threadTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Te6edf3threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)
Tf0883e@property
Tff7b72def Td2a8ffclientsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ffspawned_interfacesTb4b4b4)
Tff7b72def Td2a8ffreceived_announceTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3from_spawnedTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3from_spawnedTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffia_freq_dequeTff7b72.Td2a8ffappendTb4b4b4(Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)Tb4b4b4)
T8b949e# TODO docs
Tff7b72def Td2a8ffsent_announceTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3from_spawnedTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3from_spawnedTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffoa_freq_dequeTff7b72.Td2a8ffappendTb4b4b4(Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)Tb4b4b4)
T8b949e# do nothing as the spawned child interface will take care of rx/tx
Tff7b72def Td2a8ffprocess_incomingTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3dataTb4b4b4)Tb4b4b4:
Tff7b72pass
T8b949e# do nothing as the spawned child interface will take care of rx/tx
Tff7b72def Td2a8ffprocess_outgoingTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3dataTb4b4b4)Tb4b4b4:
Tff7b72pass
Tff7b72def Td2a8ffserveTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e# handle new websocket client connections
Tff7b72def Td2a8ffon_websocket_client_connectedTb4b4b4(Te6edf3websocketTb4b4b4: Te6edf3ServerConnectionTb4b4b4)Tb4b4b4:
T8b949e# create new child interface
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffAccepting incoming WebSocket connectionTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Te6edf3spawned_interface Tff7b72= Te6edf3WebsocketClientInterfaceTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffownerTb4b4b4,
Tb4b4b4{
Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Ta5d6fffTa5d6ff"Ta5d6ffClient on Tffd700{Tff7b72selfTff7b72.Td2a8ffnameTffd700}Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fftarget_hostTa5d6ff"Tb4b4b4: Te6edf3websocketTff7b72.Td2a8ffremote_addressTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6fftarget_portTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3websocketTff7b72.Td2a8ffremote_addressTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4)Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Te6edf3websocketTff7b72=Te6edf3websocketTb4b4b4,
Tb4b4b4)
T8b949e# configure child interface
Te6edf3spawned_interfaceTff7b72.Td2a8ffIN Tff7b72= Tff7b72selfTff7b72.Td2a8ffIN
Te6edf3spawned_interfaceTff7b72.Td2a8ffOUT Tff7b72= Tff7b72selfTff7b72.Td2a8ffOUT
Te6edf3spawned_interfaceTff7b72.Td2a8ffHW_MTU Tff7b72= Tff7b72selfTff7b72.Td2a8ffHW_MTU
Te6edf3spawned_interfaceTff7b72.Td2a8ffbitrate Tff7b72= Tff7b72selfTff7b72.Td2a8ffbitrate
Te6edf3spawned_interfaceTff7b72.Td2a8ffmode Tff7b72= Tff7b72selfTff7b72.Td2a8ffmode
Te6edf3spawned_interfaceTff7b72.Td2a8ffparent_interface Tff7b72= Tff7b72self
Te6edf3spawned_interfaceTff7b72.Td2a8ffonline Tff7b72= Tff7b72True
Te6edf3spawned_interfaceTff7b72.Td2a8ffannounce_rate_target Tff7b72= Tff7b72None
Te6edf3spawned_interfaceTff7b72.Td2a8ffannounce_rate_grace Tff7b72= Tff7b72None
Te6edf3spawned_interfaceTff7b72.Td2a8ffannounce_rate_penalty Tff7b72= Tff7b72None
T8b949e# activate child interface
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffSpawned new WebsocketClientInterface: Tffd700{Te6edf3spawned_interfaceTffd700}Ta5d6ff"Tb4b4b4,
Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4,
Tb4b4b4)
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffinterfacesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3spawned_interfaceTb4b4b4)
T8b949e# associate child interface with this interface
Tff7b72while Te6edf3spawned_interface Tff7b72in Tff7b72selfTff7b72.Td2a8ffspawned_interfacesTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffspawned_interfacesTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3spawned_interfaceTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffspawned_interfacesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3spawned_interfaceTb4b4b4)
T8b949e# run read loop
Te6edf3spawned_interfaceTff7b72.Td2a8ffread_loopTb4b4b4(Tb4b4b4)
T8b949e# client must have disconnected as the read loop finished, so forget the spawned interface
Tff7b72selfTff7b72.Td2a8ffspawned_interfacesTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3spawned_interfaceTb4b4b4)
T8b949e# run websocket server
Tff7b72tryTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffStarting Websocket server for Tffd700{Tff7b72selfTffd700!s}Ta5d6ff...Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72with Te6edf3serveTb4b4b4(
Te6edf3on_websocket_client_connectedTb4b4b4,
Tff7b72selfTff7b72.Td2a8fflisten_ipTb4b4b4,
Tff7b72selfTff7b72.Td2a8fflisten_portTb4b4b4,
Te6edf3compressionTff7b72=Tff7b72NoneTb4b4b4,
Tb4b4b4) Tff7b72as Te6edf3serverTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffonline Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffserver Tff7b72= Te6edf3server
Te6edf3serverTff7b72.Td2a8ffserve_foreverTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Tffd700{Tff7b72selfTffd700}Ta5d6ff failed with error: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
T8b949e# websocket server is no longer running, let's restart it
Tff7b72selfTff7b72.Td2a8ffonline Tff7b72= Tff7b72False
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffWebsocket server stopped for Tffd700{Tff7b72selfTffd700!s}Ta5d6ff...Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(Tff7b72selfTff7b72.Td2a8ffRESTART_DELAY_SECONDSTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffserveTb4b4b4(Tb4b4b4)
Tff7b72def Td2a8ffdetachTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e# mark as offline
Tff7b72selfTff7b72.Td2a8ffonline Tff7b72= Tff7b72False
T8b949e# stop websocket server
Tff7b72if Tff7b72selfTff7b72.Td2a8ffserver Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffserverTff7b72.Td2a8ffshutdownTb4b4b4(Tb4b4b4)
T8b949e# mark as detached
Tff7b72selfTff7b72.Td2a8ffdetached Tff7b72= Tff7b72True
T8b949e# set interface class RNS should use when importing this external interface
Te6edf3interface_class Tff7b72= Te6edf3WebsocketServerInterface
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────